<?php

namespace app\python\service;

use qiniu\QiNiuCloud;
use think\Image;
use app\common\RootService;
use app\common\model\SourceModel;
use app\common\model\ContentModel;
use app\common\model\CategoryModel;
use app\python\validate\TaskValidate;
use app\common\model\ContentBodyModel;
use aliyun\AliyunOssCloud;

class TaskService extends RootService
{
    /**
     * 任务列表
     * @return array
     */
    public function lists()
    {
        // 内容来源
        $sourceList = $this->sourceList();
        // 采集任务(过滤禁用的栏目)
        CategoryModel::where(['state' => 0, 'type' => 0])->chunk(100, function ($rows) use ($sourceList, &$taskList) {
            foreach ($rows as $row) {
                if (!empty($row['task'])) {
                    foreach ($row['task'] as $task) {
                        if (isset($sourceList[$task['sourceId']])) {
                            $taskList[] = ['catId' => $row['id'], 'sourceId' => $task['sourceId'], 'url' => $task['url'],
                                'number' => $task['number'], 'domain' => $sourceList[$task['sourceId']]];
                        }
                    }
                }
            }
        }, 'rank', 'asc');
        // 返回任务列表
        return $taskList ?? [];
    }

    /**
     * 添加文章
     * @param array $params
     * @return string[]
     * @throws \app\common\RootException
     */
    public function addContent(array $params)
    {
        // 参数校验
        $this->validate(new TaskValidate, 'add');
        // 栏目校验
        if (!in_array($params['catId'], $this->categoryIds())) {
            $this->errorException('栏目无效');
        }
        // 来源校验
        if (!isset($this->sourceList()[$params['sourceId']])) {
            $this->errorException('来源无效');
        }
        // 新增操作
        $addData = ['cat_id' => $params['catId'], 'source_id' => $params['sourceId'], 'title' => $params['title'],
            'state' => 1, 'link' => $params['link'], 'icon' => $params['icon'], 'flag_key' => $params['flagKey']];
        // 类型判断
        empty($params['video']) || $addData['type'] = 1;
        // 内容标签
        empty($params['label']) || $addData['label'] = $params['label'];
        // 视频地址
        empty($params['video']) || $addData['video'] = $params['video'];
        // 文章描述
        empty($params['brief']) || $addData['brief'] = $params['brief'];
        // 备注
        empty($params['remark']) || $addData['remark'] = $params['remark'];
        $contentModel = new ContentModel();
        // 添加成功
        try {
            $contentModel->startTrans();
            if ($contentInfo = ContentModel::create($addData)) {
                ContentBodyModel::create(['content_id' => $contentInfo['id'], 'content' => $params['content']]);
                // 主图
                $contentImg = $this->distinctIcon($contentInfo['id'], $params['content']) ?: [$params['icon']];
                // 从内容页面提取缩略图
                $contentInfo->image = $contentImg;
                // 缩略图压缩上传CDN
                empty($contentImg[0]) || $contentInfo->thumb = [$this->thumbImage($contentImg[0])];
                $contentInfo->save();
            }
            $contentModel->commit();
            return ['msg' => '添加成功' . $contentInfo['id']];
        } catch (\Exception $e) {
            // 添加失败
            $this->errorException('添加失败' . $e->getMessage());
        }
    }

    /**
     * 查询已经采集的文章
     * @param array $params
     * @return array
     */
    public function being(array $params)
    {
        return ContentModel::where(['flag_key' => $params['flagKeys']])->column('flag_key');
    }

    /**
     * 删除文章
     * @param int $contentId
     * @return string[]
     * @throws \app\common\RootException
     */
    public function del(int $contentId)
    {
        ContentModel::where(['id' => $contentId])->delete() || $this->errorException('衫裤跑路失败。。。');
        return ['msg' => '衫裤跑路成功o(*￣︶￣*)o'];
    }

    /**
     * 生成缩略图
     * @throws \Exception
     */
    public function generateThumb()
    {
        $startId = 129069;
        ContentModel::where([['id', '>', $startId]])->chunk(10, function ($rows) {
            foreach ($rows as $row) {
                if (!empty($row['icon'])) {
                    $row->thumb = [$this->thumbImage($row['image'][0])];
                    $row->save();
                    echo "文章ID {$row['id']}处理成功：" . date('Y-m-d H:i:s') . "\n";
                }
            }
        });
    }

    /**
     * 裁剪缩略图
     * @param string $imgUrl
     * @return string
     * @throws \Exception
     */
    public function thumbImage(string $imgUrl = '')
    {
        if (empty($imgUrl)) {
            return '';
        }
        // 缩略图大小
        $imageSize = [480, 400];
        // 缩略图保存目录
        $thumbDir = 'images/thumb/' . date('Ymd') . '/';
        // 自动创建目录
        is_dir($thumbDir) || mkdir($thumbDir, 0755, true);
        // 下载原图
        $originalImg = $this->originalImgDownload($imgUrl);
        // 读取图片信息
        $originalImgInfo = $this->imgInfo($originalImg);
        // 打开图片
        $image = Image::open($originalImg);
        // 缩略图名称
        $thumbName = $thumbDir . join('.', $originalImgInfo);
        // 60%压缩比例
        $image->thumb($imageSize[0], $imageSize[1])->save($thumbName, null, 60);
        // 上传图片到CDN
//         QiNiuCloud::cloudImg($thumbName, true);
        // 上传图片到阿里云CDN暂时注释
        AliyunOssCloud::cloudImg($thumbName, true);
            
        return $thumbName;
    }

    /**
     * 原图下载
     * @param string $imageUrl
     * @return string
     */
    protected function originalImgDownload(string $imageUrl)
    {
        // 原图保存目录
        $originalDir = 'images/original/' . date('Ymd') . '/';
        // 自动创建目录
        is_dir($originalDir) || mkdir($originalDir, 0755, true);
        // 解析图片信息
        $imageInfo = $this->imgInfo($imageUrl);
        // 保存名称
        $saveName = $originalDir . join('.', $imageInfo);
        // 忽略忽略证书证书下载
        $streamOpts = ["ssl" => ["verify_peer"=>false, "verify_peer_name"=>false]];
        // 下载图片
        file_put_contents($saveName, file_get_contents($imageUrl, false, stream_context_create($streamOpts)));
        return $saveName;
    }

    /**
     * 解析图片地址
     * @param string $imageUrl
     * @return false|string[]
     */
    protected function imgInfo(string $imageUrl)
    {
        // 解析图片地址
        $urlInfo = explode('/', explode('?', $imageUrl)[0]);
        // 解析图片信息
        return explode('.', $urlInfo[count($urlInfo) - 1]);
    }

    /**
     * 封面图片去重（不包含缩略图）
     * @param array $icon
     * @param array $content
     * @return array
     */
    protected function distinctIcon(int $contentId, array $contentBody)
    {
        $images = [];
        // 判断显示1张还是3张
        $iconRand = $contentId % 5;
        // 获取内容图片
        array_walk($contentBody, function ($row) use (&$images) {
            if (in_array($row['type'], ['img'])) {
                array_push($images, $row['body']);
            }
        });
        return $iconRand && count($images) > 2 ? array_slice($images, 0, 3) : (isset($images[0]) ? [$images[0]] : []);
    }

    /**
     * 资源ID
     * @return array
     */
    protected function sourceList()
    {
        return SourceModel::where(['state' => 0])->column('domain', 'id');
    }

    /**
     * 栏目ID
     * @return array
     */
    protected function categoryIds()
    {
        return CategoryModel::where(['state' => 0])->column('id');
    }
}